package it.bit.jlightqueryer.conn;

import java.io.IOException;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * This class identify a Connection used in JLightQueryer.<br>
 * Indentify a relative java.sql.Connection and a Connection used in recent connections
 * @author PerezDeQueya80
 */
public class Connection {
    private java.sql.Connection connection;
    private Driver driver;
    private String[] values;
    private boolean savepassword;
    private String username;
    private String password;

    /**
     * Constructor from a recent connection
     * @param recents
     * @param index
     * @throws Exception if original Driver is not found.
     */
    public Connection(Recents recents, int idx) throws Exception {
        this.driver = Drivers.get(recents.getProperty(idx,"driver"));
        if (driver!= null) {
            String[] variables = driver.getVariables();
            this.values = new String[variables.length];
            for (int i = 0; i < variables.length; i++) {
                String var = variables[i];
                this.values[i] = recents.getProperty(idx,"var."+var);
            }
            this.savepassword = "1".equals(recents.getProperty(idx,"savepassword"));
            this.username = recents.getProperty(idx,"username");
            this.password = recents.getProperty(idx,"password");
        }
        else
            throw new Exception("Driver id "+recents.getProperty(idx,"driver")+" not found");
    }

    /**
     * Constructor from single values
     * @param relative Driver
     * @param values for driver variables
     * @param db username
     * @param db password
     */
    public Connection(Driver driver, String[] values, boolean savepassword, String username, String password) {
        this.driver = driver;
        this.values = values;
        this.savepassword = savepassword;
        this.username = username;
        this.password = password;
    }

    /**
     * Add itself to Recents
     * @param recents
     * @throws IOException
     */
    public void addToRecents(Recents recents) throws IOException {
        int count = recents.getCount();
        recents.setCount(count+1);
        setToRecents(recents, count);
    }

    /**
     * Set itself to a specific position to Recents
     * @param recents
     * @param idx
     * @throws IOException
     */
    public void setToRecents(Recents recents, int idx) throws IOException {
        recents.setProperty(idx, "driver", driver.getId());
        String[] variables = driver.getVariables();
        for (int i = 0; i < values.length; i++) {
            String value = values[i];
            recents.setProperty(idx, "var."+variables[i], value);
        }
        recents.setProperty(idx, "savepassword", savepassword ? "1" : "0");
        recents.setProperty(idx, "username", username);
        if (savepassword) {
        	recents.setProperty(idx, "password", password);
        }
        else {
        	recents.setProperty(idx, "password", "");
        }
        recents.save();
    }

    /**
     * Comprensive description
     */
    public String toString() {
        return username+"@"+getUrl();
    }

    /**
     * @return the URL with valorized variables
     */
    public String getUrl() {
        return driver.setVariables(values);
    }

    /**
     * Open main connection
     * @throws SQLException
     */
    public void openConnection() throws SQLException {
        if (connection == null || connection.isClosed()) {
//			Class.forName("...");
            DriverManager.registerDriver(getDriver().getDriver());
            System.out.println("Driver "+getDriver().getDriver()+" loaded.");
            connection = DriverManager.getConnection(
                    getUrl()
                    , username
                    , password
            );
        }
    }

    /**
     * Close main connection
     * @throws SQLException
     */
    public void closeConnection() throws SQLException {
        if (connection != null && !connection.isClosed()) {
            connection.close();
        }
    }

    /**
     * Return main connection. Ensure that connection is opened too.
     * @return main Connection
     * @throws SQLException
     */
    public java.sql.Connection getConnection() throws SQLException {
        openConnection();
        return connection;
    }

    /**
     * Commit on main connection
     * @throws SQLException
     */
    public void commit() throws SQLException {
        getConnection().commit();
    }

    /**
     * Rollback on main connection
     * @throws SQLException
     */
    public void rollback() throws SQLException {
        getConnection().rollback();
    }

    /**
     * Return isClosed() on main connection
     * @return
     * @throws SQLException
     */
    public boolean isClosed() throws SQLException {
        return getConnection().isClosed();
    }

    /**
     * Return isClosed() on main connection
     * @return
     * @throws SQLException
     */
    public void close() throws SQLException {
        getConnection().close();
    }

    public Driver getDriver() {
        return driver;
    }

    public void setDriver(Driver driver) {
        this.driver = driver;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String[] getValues() {
        return values;
    }

    public void setValues(String[] values) {
        this.values = values;
    }

    public boolean isSavePassword() {
        return savepassword;
    }

    public void setSavePassword(boolean savePassword) {
        this.savepassword = savePassword;
    }

    /**
     * Usefull to give comprensive JTable values
     * @return
     */
    public Object[] toTableRow() {
        return new Object[] {
            getUsername()
            , getUrl()
        };
    }

}
